/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2024-05-18     liuchao       the first version
 */
#define LOG_TAG "app_net"
#include <ulog.h>
#include "app_net.h"
#include <netdev_ipaddr.h>
#include <netdev.h>
#include "aliyun.h"
#include "rotate.h"
#include "drv_sensor.h"
#include "ntp.h"
#include "device.h"
#include "sleep.h"
#include "drv_ec.h"

int is_ethernet_up(int wait_until_up)
{
    while (1)
    {
        struct netdev* n = netdev_get_by_name("e0");
        if (n && netdev_is_internet_up(n))
        {
            LOG_D("Ethernet is up");
            return 1;
        }
        else
        {
            if (wait_until_up)
            {
                LOG_D("Waiting for ethernet up");
                rt_thread_mdelay(wait_until_up);
            }
            else
            {
                return 0;
            }
        }
    }
}

static rt_uint32_t s_pub_retries = 0;
void reboot(uint8_t argc, char **argv);
static rt_tick_t s_pub_ts = 0;
static rt_uint32_t s_up_counts = 0;

int app_pub_running_properties()
{
    if (s_up_counts == 0)
    {
        s_up_counts = configuration_get_uint32(CONFIGURATION_UP_COUNTS);
    }
    int ret = 0;
    rt_tick_t up_time = rt_tick_get_millisecond();
    if (up_time < 10000)
    {
        ret = 0;
        goto done;
    }

    float v = 0;

    cJSON* properties = cJSON_CreateObject();

    v = sensor_axial(SENSOR_OIL_PRESSURE);
    cJSON_AddNumberToObject(properties, "pressureVal", v);

    v = sensor_distance(SENSOR_GEAR_DISTANCE);
    cJSON_AddNumberToObject(properties, "gearDistance", v);

    v = sensor_distance(SENSOR_PUTTER_DISTANCE);
    cJSON_AddNumberToObject(properties, "putterDistance", v);

    v = sensor_voltage(SENSOR_BATTERY);
    cJSON_AddNumberToObject(properties, "batteryVoltage", v);

    cJSON_AddNumberToObject(properties, "oilAmount", sensor_oil_volume(SENSOR_OIL_VOLUME));

    cJSON* j_device_info = cJSON_CreateObject();
    cJSON_AddNumberToObject(j_device_info, "YYZtime", hy_ms() / 1000);
    cJSON_AddNumberToObject(j_device_info, "runTime", rt_tick_get_millisecond() / 1000);
    cJSON_AddNumberToObject(j_device_info, "runCount", s_up_counts);
    cJSON_AddItemToObject(properties, "deviceInfo", j_device_info);

    int i = device_status();
    cJSON_AddNumberToObject(properties, "deviceStatus", i);

    ret = aliyun_pub_properties(properties);
    cJSON_Delete(properties);

    if (ret > 0)
    {
        ret = 1;
        s_pub_retries = 0;
    }
    else
    {
        s_pub_retries++;
        LOG_E("pub properties failed %lu times", s_pub_retries);
#if 0
        if (configuration_is_mqtt_host_valid() && ((up_time - s_pub_ts) >= (300 * 1000))
                && (device_status() == DEVICE_STATUS_AUTO))
        {
            //ec_disable();
            //rt_thread_mdelay(5000);
            //ec_enable();
            ec_disable();
            rt_thread_mdelay(10000);
            standby_seconds(5);
            //rt_hw_cpu_reset();
        }
#endif
    }

    done:
    if (ret == 0)
    {
        s_pub_ts = up_time;
    }
    return ret;
}

static void report_handler(void *arg)
{
    if (!is_ethernet_up(0))
    {
        return;
    }
    /*
     local time: Thu May 23 23:47:40 2024
     timestamps: 1716479260
     timezone: UTC+8
     */
    struct timeval tv = { 0 };
    struct timezone tz = { 0 };

    gettimeofday(&tv, &tz);
    if (tv.tv_sec < 1716479260)
    {
        LOG_I("ntp sync: %d", ntp_sync_to_rtc(NULL));
    }
    if (auto_mode_baseline() == 0 || auto_mode_percentage() == 0)
    {
        aliyun_pub_property_float("pressureSet", auto_mode_baseline());
        aliyun_pub_property_float("pressureGap", auto_mode_percentage() * 100.0);
        aliyun_get_property_desired("pressureSet", "pressureGap", NULL);
    }

    if (auto_mode_update_inverval() == -1 || auto_mode_update_delay() == -1)
    {
        aliyun_pub_property_int32("updateInterval", auto_mode_update_inverval());
        aliyun_pub_property_int32("updateDelay", auto_mode_update_delay());
        aliyun_get_property_desired("updateInterval", "updateDelay", "PauseSwitch", NULL);
    }

    if (battery_low_threshold_get() < 0)
    {
        aliyun_get_property_desired("LowBAT", NULL);
    }
}

static int app_net_init()
{
    ulog_tag_lvl_filter_set(LOG_TAG, LOG_LVL_INFO);
    s_pub_ts = rt_tick_get_millisecond();
    rt_timer_t t = rt_timer_create("rep", report_handler, NULL, rt_tick_from_millisecond(10000),
    RT_TIMER_FLAG_PERIODIC | RT_TIMER_FLAG_SOFT_TIMER);
    rt_timer_start(t);
    return RT_EOK;
}
INIT_APP_EXPORT(app_net_init);
